package cloud.xlh.my_system.in;

import cloud.xlh.domin.DO.MonitorCounterDO;
import cloud.xlh.domin.dto.UserDTO;
import cloud.xlh.domin.po.UserPO;
import cloud.xlh.domin.vo.CommonRspVO;
import cloud.xlh.domin.vo.UserVO;
import cloud.xlh.gencontrollerprocessorstarter.processor.gencontroller.annotation.ServiceMapping;
import cloud.xlh.infrastructure.getter_and_setter.service.Generator4MethodAccessor;
import cloud.xlh.infrastructure.getter_and_setter.service.MethodAccessor;
import cloud.xlh.infrastructure.utils.CommonUtil;
import cloud.xlh.my_system.beanpostprocessor.MeterRegistryBeanPostProcessor;
import cloud.xlh.my_system.flow.UserRegisterFlow;
import cloud.xlh.my_system.pojo.JsonContext;
import cloud.xlh.my_system.tradeflow.EcnyTradeContext;
import cloud.xlh.my_system.tradeflow.TradeFlowRuner;
import cloud.xlh.utils.StackTraceUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : xlh_osms
 * @ Author: XuLeHuang
 * @ Date: 2023/1/3 11:45
 * @ Description: 服务统一入口 此类中所有方法不可出现lambda表达式
 */
@Slf4j
@Component
public class ServiceIn {
    @Autowired
    private TradeFlowRuner tradeFlowRuner;
    @Autowired
    private MeterRegistry meterRegistry;

    @Resource
    private MeterRegistryBeanPostProcessor meterRegistryBeanPostProcessor;


    @ServiceMapping(path = "1d01", channel = "esb")
    public void svc_1d01(JsonContext jsonContext) {

        MonitorCounterDO monitorCounterDO = meterRegistryBeanPostProcessor.getMonitorCounterDO();
        monitorCounterDO.getRequestTotalTimes().increment();
        log.info("1d01成功调用");
        /**
         * todo
         * 为何使用Optional的lambda表达式反射会一个代理方法
         * 而且target下类文件文件看不出，感觉运行时生成的，又或者在class文件
         * */
        /*Optional.ofNullable(jsonContext).ifPresent(jsonContext1 -> {
            log.info("reqJsonObject->{}", jsonContext1.getReqJsonObject());
            JSONObject rspJsonObject = jsonContext1.getRspJsonObject();
            rspJsonObject.put("retCode", "PR00");
            jsonContext1.setRspJsonObject(rspJsonObject);
            log.info("rspJsonObject->{}", jsonContext1.getRspJsonObject());
        });*/
        if (jsonContext != null) {
            log.info("reqJsonObject->{}", jsonContext.getReqJsonObject());
            UserDTO userDTO = JSONObject.toJavaObject(jsonContext.getReqJsonObject(), UserDTO.class);
            /**
             * 执行流程类
             * */
            //UserDTO userRegisterInfoDTO = (UserDTO) tradeFlowRuner.execute(UserRegisterFlow.TRADE_FLOW, EcnyTradeContext.getInstance(userDTO));
            UserVO userVO = new UserVO();
            /**
             * 忽略大小写拷贝 
             * */
            //CommonUtil.copyPropertiesIgnoreCase(userRegisterInfoDTO, userVO);
            CommonRspVO commonRspVO = new CommonRspVO<UserVO>().builder
                    .retCode("PR00")
                    .retInfo("SUCCESS")
                    .data(userVO)
                    .build();
            JSONObject commonRspVOJsonObject = (JSONObject) JSON.toJSON(commonRspVO);
            jsonContext.setRspJsonObject(commonRspVOJsonObject);
            /*JSONObject rspJsonObject = jsonContext.getRspJsonObject();
            rspJsonObject.put("retCode", "PR00");
            jsonContext.setRspJsonObject(rspJsonObject);
            log.info("rspJsonObject->{}", jsonContext.getRspJsonObject());*/
        }
    }

    @ServiceMapping(path = "1d02", channel = "esb")
    public void svc_1d02(JsonContext jsonContext) {
        log.info("1d02成功调用");
    }

    @ServiceMapping(path = "1d03", channel = "esb")
    public void svc_1d03(JsonContext jsonContext) {
        log.info("1d03成功调用，log print location is -> {}", StackTraceUtil.getCurrentLocation(Thread.currentThread()));
        /**
         * todo
         * 为何使用Optional的lambda表达式反射会一个代理方法
         * 而且target下类文件文件看不出，感觉运行时生成的，又或者在class文件
         * */
        /*Optional.ofNullable(jsonContext).ifPresent(jsonContext1 -> {
            log.info("reqJsonObject->{}", jsonContext1.getReqJsonObject());
            JSONObject rspJsonObject = jsonContext1.getRspJsonObject();
            rspJsonObject.put("retCode", "PR00");
            jsonContext1.setRspJsonObject(rspJsonObject);
            log.info("rspJsonObject->{}", jsonContext1.getRspJsonObject());
        });*/
        if (jsonContext != null) {
            log.info("reqJsonObject->{}", jsonContext.getReqJsonObject());
            UserDTO userDTO = JSONObject.toJavaObject(jsonContext.getReqJsonObject(), UserDTO.class);
            /**
             * 执行流程类
             * */
            UserDTO userRegisterInfoDTO = (UserDTO) tradeFlowRuner.execute(UserRegisterFlow.TRADE_FLOW, EcnyTradeContext.getInstance(userDTO));
            UserVO userVO = new UserVO();
            /**
             * 忽略大小写拷贝
             * */
            CommonUtil.copyPropertiesIgnoreCase(userRegisterInfoDTO, userVO);
            CommonRspVO commonRspVO = new CommonRspVO<UserVO>().builder
                    .retCode("PR00")
                    .retInfo("SUCCESS")
                    .data(userVO)
                    .build();
            JSONObject commonRspVOJsonObject = (JSONObject) JSON.toJSON(commonRspVO);
            jsonContext.setRspJsonObject(commonRspVOJsonObject);
            /*JSONObject rspJsonObject = jsonContext.getRspJsonObject();
            rspJsonObject.put("retCode", "PR00");
            jsonContext.setRspJsonObject(rspJsonObject);
            log.info("rspJsonObject->{}", jsonContext.getRspJsonObject());*/
        }
    }

    @ServiceMapping(path = "1d04", channel = "esb")
    public void svc_1d04(JsonContext jsonContext) {
        log.info("1d04成功调用，log print location is -> {}", StackTraceUtil.getCurrentLocation(Thread.currentThread()));
        JSONObject jsonObject = new JSONObject();
        JSONObject head = new JSONObject();
        JSONObject body = new JSONObject();
        head.put("retCode", "PR00");
        head.put("retInfo", "SUCCESS");
        body.put("hotDataKey", "hotDataValue");
        jsonObject.put("head" , head);
        jsonObject.put("body" , body);
        jsonContext.setRspJsonObject(jsonObject);
    }
}

